#include <QCoreApplication>
#include <QDebug>
#define __STDC_CONSTANT_MACORS

#ifdef _WIN32
//windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
}
#else
//linux
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#ifdef __cplusplus
};
#endif
#endif

//FIX
struct URLProtocol;
/**
 * @brief urlprotocolinfo protocol support information
 * @return
 */
char * urlprotocolinfo(){
    char *info=(char*)malloc(40000);
    memset(info,0,40000);
    av_register_all();
    struct URLProtocol *pup = NULL;
    // Input
    struct URLProtocol **p_temp = &pup;
    avio_enum_protocols((void **)p_temp,0);
    while((*p_temp)!=NULL){
        sprintf(info, "%s[In ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0));
    }
    pup = NULL;
    // output
    avio_enum_protocols((void**)p_temp,1);
    while((*p_temp)!=NULL){
        sprintf(info, "%s[Out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1));
    }
    return info;
}

char * avformatinfo(){
    char * info=(char*)malloc(40000);
    memset(info,0,40000);

    av_register_all();
    AVInputFormat *if_temp = av_iformat_next(NULL);
    AVOutputFormat *of_temp = av_oformat_next(NULL);

    // INPUT
    while(if_temp!=NULL){
        sprintf(info, "%s[In ] %10s \n",info,if_temp->name);
        if_temp = if_temp->next;
    }
    while(of_temp!=NULL){
        sprintf(info, "%s[Out ] %10s \n" , info,of_temp->name);
        of_temp = of_temp->next;
    }
    return info;
}
/**
 * @brief avcodecinfo AVCodec support information
 * @return
 */
char * avcodecinfo(){
    char *info=(char *)malloc(40000);
        memset(info,0,40000);

        av_register_all();

        AVCodec *c_temp = av_codec_next(NULL);

        while(c_temp!=NULL){
            if (c_temp->decode!=NULL){
                sprintf(info, "%s[Dec]", info);
            }
            else{
                sprintf(info, "%s[Enc]", info);
            }
            switch (c_temp->type){
            case AVMEDIA_TYPE_VIDEO:
                sprintf(info, "%s[Video]", info);
                break;
            case AVMEDIA_TYPE_AUDIO:
                sprintf(info, "%s[Audio]", info);
                break;
            default:
                sprintf(info, "%s[Other]", info);
                break;
            }

            sprintf(info, "%s %10s\n", info, c_temp->name);

            c_temp=c_temp->next;
        }
        return info;
}

/**
 * AVFilter Support Information
 */
char * avfilterinfo()
{
    char *info=(char *)malloc(40000);
    memset(info,0,40000);

    avfilter_register_all();

    AVFilter *f_temp = (AVFilter *)avfilter_next(NULL);

    while (f_temp != NULL){
        sprintf(info, "%s[%15s]\n", info, f_temp->name);
        f_temp=f_temp->next;
    }
    return info;
}

/**
 * Configuration Information
 */
char * configurationinfo()
{
    char *info=(char *)malloc(40000);
    memset(info,0,40000);

    av_register_all();

    sprintf(info, "%s\n", avcodec_configuration());

    return info;
}


int main(int argc, char *argv[])
{
    qDebug() << "Hello begining" <<endl;
    QCoreApplication a(argc, argv);

    char *infostr=NULL;
    infostr = configurationinfo();
    qDebug() << " <<Configuration>> " << infostr << endl;
    free(infostr);

    infostr = urlprotocolinfo();
    qDebug() << " <<URLProtocol>> " << infostr << endl;
    free(infostr);

    infostr = avformatinfo();
    qDebug() << " <<AVFormat>> " << infostr << endl;
    free(infostr);

    infostr = avcodecinfo();
    qDebug() << " <<AVCodec>> " << infostr << endl;
    free(infostr);

    infostr=avfilterinfo();
    qDebug() << " <<AVFilter>> " << infostr << endl;
    free(infostr);

    return a.exec();
}

